import math
import re

'''
c = Coordinate("-122.5 , 45.5")
d = Coordinate("7646000 , 682000")
e = Coordinate(-122.5, 45.5)
f = Coordinate(7646000,682000)
m = Coordinate.looksLikeCoordinate("-122.5 , 45.5")
n = Coordinate.looksLikeCoordinate("-122N,45.5")
print m, n
'''
class Coordinate:
    COORD_REGEXP = re.compile("[\\s]*[0-9\\-.]+[,\\s]+[0-9\\-.]+[\\s]*")
    splitter = ",";

    def __init__(self, x, y=None):
        # step 1: we either get an x & y or a string we have to split
        #if y is None:
        if y is None:
            x,y = Coordinate.split(x)

        # assign 
        self.m_x   = x
        self.m_y   = y
        self.m_lon = x
        self.m_lat = y

        if x < 180 and y < 180:
            self.llToOrStatePlaneNorth();
        else:
            self.statePlaneNorthToLL();

    def llToOrStatePlaneNorth(self):
        XCOORD = self.m_lon
        YCOORD = self.m_lat
        if XCOORD is None or YCOORD is None:
            return;

        x = ((6350713.93 -(111123.3583*(YCOORD-45.1687259619)+9.77067* math.pow(YCOORD-45.1687259619, 2) + 5.62487 * math.pow(YCOORD-45.1687259619, 3) + 0.024544 * math.pow(YCOORD-45.1687259619, 4) ))* math.sin(((3.14159265359*((120.5+XCOORD) * math.sin(45.1687259*3.14159265359/180)))/180))+2500000)/0.3048;
        y = ((111123.3583*(YCOORD-45.1687259619)+9.77067* math.pow(YCOORD-45.1687259619, 2)+5.62487*math.pow(YCOORD-45.1687259619, 3)+0.024544*math.pow(YCOORD-45.1687259619, 4))+(((6350713.93-(111123.3583*(YCOORD-45.1687259619)+9.77067*math.pow(YCOORD-45.1687259619, 2)+5.62487*math.pow(YCOORD-45.1687259619, 3)+0.024544*math.pow(YCOORD-45.1687259619,4)))*math.sin((3.14159265359*((120.5+XCOORD)*math.sin(45.1687259*3.14159265359/180)))/180))*math.tan((3.14159265359*((120.5+XCOORD)*math.sin(45.1687259*3.14159265359/180)))/360))+166910.7663)/0.3048;

        self.m_x = round(x,1);
        self.m_y = round(y,1);


    def statePlaneNorthToLL(self):
        xCoord = self.m_x
        yCoord = self.m_y
        if xCoord is None or yCoord is None:
            return;

        lon = +((((math.atan(((xCoord*0.3048)-2500000)/(6350713.93-((yCoord*0.3048)-166910.7663))))*180)/(3.14159265359*0.709186016884))-120.5);
        lat = (45.1687259619+((((yCoord*0.3048)-166910.7663)-(((xCoord*0.3048)-2500000)*math.tan((math.atan(((xCoord*0.3048)-2500000)/(6350713.93-((yCoord*0.3048)-166910.7663))))/2)))*(0.000008999007999+(((yCoord*0.3048)-166910.7663)-(((xCoord*0.3048)-2500000)*math.tan((math.atan(((xCoord*0.3048)-2500000)/(6350713.93-((yCoord*0.3048)-166910.7663))))/2)))*(-7.1202E-015+(((yCoord*0.3048)-166910.7663)-(((xCoord*0.3048)-2500000)*math.tan((math.atan(((xCoord*0.3048)-2500000)/(6350713.93-((yCoord*0.3048)-166910.7663))))/2)))*(-3.6863E-020+(((yCoord*0.3048)-166910.7663)-(((xCoord*0.3048)-2500000)*math.tan((math.atan(((xCoord*0.3048)-2500000)/(6350713.93-((yCoord*0.3048)-166910.7663))))/2)))*-1.3188E-027)))));

        self.m_lon = lon
        self.m_lat = lat


    def split(str):
        splitter = Coordinate.splitter
        if splitter not in str:
            splitter = " " 

        # step 2: split the X and Y parts of the string
        xy = str.split(splitter);
        x = float(xy[0])
        y = float(xy[1])
        return x,y
    split = staticmethod(split)


    def looksLikeCoordinate(str):
        if str is not None and Coordinate.COORD_REGEXP.match(str):
            return True;
        return False;
    looksLikeCoordinate = staticmethod(looksLikeCoordinate)


    def looksLikeStatePlaneCoordinate(str):
        if Coordinate.looksLikeCoordinate(str):
            x,y = Coordinate.split(str)
            if x > 180 and y > 180:
                return True;
            
        return False;
    looksLikeStatePlaneCoordinate = staticmethod(looksLikeStatePlaneCoordinate)


    def getLonLat(self):
        return str(self.m_lon) + "," + str(self.m_lat)
